﻿using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Autofac;
using AxLIVEXLib;
using LIVEXLib;
using ComputerVision.ANN;
using ComputerVision.BaseForm;
using ComputerVision.Common;
using ComputerVision.Data;
using ComputerVision.Services;
using System;
using System.Drawing;
using RawInput_dll;
using ZnakovMD;

namespace ComputerVision
{
    public partial class frmXeVaoNew : frmObject
    {
        private readonly RawInput _rawinput;
        private IService<ConfigrationCamera> _configCamera;
        private IService<LoaiXe> _loaiXe;
        private readonly IService<Config> _configService;
        private IService<XeTemp> _xe;
        private IService<VeXe> _veXe;
        private VeXe _veXe2;
        private XeTemp _xe2;
        private XeTemp _model = null;

        private string _computerName;
        private int _soLuong;

        private Bitmap imgT = null;
        private Bitmap imgS = null;
        private Random rand;
        private string _veXeDap;
        private string cardNumber = string.Empty;
        private bool isCardReaderVao = false;
        private bool isCardReaderRa = false;
        private bool readOk = false;
        private bool userType = false;
        private string tempNumber = string.Empty;
        private string readerDevideVao = string.Empty;
        private string readerDevideRa = string.Empty;

        private string tempFile = string.Empty;
        private ImgageArrayVao imageArray;
        private FileUtil fileUtil;
        private int countT = 0;
        private int countS = 0;
        private string cardStatus = string.Empty;
        private string _veTemp = string.Empty;
        private int autoCount = 0;

        private CustomControl.OrientAbleTextControls.OrientedTextLabel orientedTextLabel12;

        IZnakov lpr;
        private IProcessor proc;
        List<Candidate> cds;

        #region Handle methods

        public frmXeVaoNew()
        {
            InitializeComponent();

            this.orientedTextLabel12 = new CustomControl.OrientAbleTextControls.OrientedTextLabel();
            PanelLeftTopLeft.Controls.Add(this.orientedTextLabel12);

            this.orientedTextLabel12.Location = new System.Drawing.Point(391, 18);
            this.orientedTextLabel12.Name = "orientedTextLabel12";
            this.orientedTextLabel12.RotationAngle = 90;
            this.orientedTextLabel12.Size = new System.Drawing.Size(16, 104);
            this.orientedTextLabel12.TabIndex = 5;
            this.orientedTextLabel12.Text = "How is this Control?";
            this.orientedTextLabel12.TextDirection = CustomControl.OrientAbleTextControls.Direction.Clockwise;
            this.orientedTextLabel12.TextOrientation = CustomControl.OrientAbleTextControls.Orientation.Rotate;

            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            _rawinput = new RawInput(Handle);
            _rawinput.CaptureOnlyIfTopMostWindow = true;    // Otherwise default behavior is to capture always
            _rawinput.AddMessageFilter();                   // Adding a message filter will cause keypresses to be handled
            _rawinput.KeyPressed += OnKeyPressed;

            _computerName = Environment.MachineName;
            _configCamera = Program.Container.Resolve<IService<ConfigrationCamera>>();
            _loaiXe = Program.Container.Resolve<IService<LoaiXe>>();
            _xe = Program.Container.Resolve<IService<XeTemp>>();
            _veXe = Program.Container.Resolve<IService<VeXe>>();
            _configService = Program.Container.Resolve<IService<Config>>();
            //_process = new ImageProcess();
            //_soVe = txtSoVe.Text;
            this.ActiveControl = txtSoVe;
            LoadLoaiXe();

            fileUtil = new FileUtil();
            lpr = Znakov.Setup();
            //read license
            lpr.set_productKey(Encoding.UTF8.GetBytes(Utilities.Dec(Constants.Map)));
            lpr.set_countryWeight("Vietnam", 1.0f);
            lpr.realizeCountryWeights();
            proc = lpr.createProcessor();

            axLiveTruoc.OnGetPicture += new AxLIVEXLib._DLiveXEvents_OnGetPictureEventHandler(axLiveTruoc_OnGetPicture);
            axLiveSau.OnGetPicture += new AxLIVEXLib._DLiveXEvents_OnGetPictureEventHandler(axLiveSau_OnGetPicture);
        }

        void axLiveSau_OnGetPicture(object sender, AxLIVEXLib._DLiveXEvents_OnGetPictureEvent e)
        {
            if (countS == 1)
            {
                return;
            }
            countS = 1;
            axLiveSau.StartGrapImage(false);
            imgS = ImageProcess.ImageConvert.GetImageFromIPicture(e.mPict);

            //_img1End = imgS;
            picSau.Image = imgS;

            if (fileUtil.WriteImage(picSau.Image, imageArray.NameSau, "V"))
            {
                //wroteImage2 = true;

                ValidCard();
                if (cardStatus == string.Empty)
                {
                    var loaiXe = cbLoaixe.SelectedItem as LoaiXe;
                    _model = new XeTemp()
                        {
                            Id = Guid.NewGuid(),
                            LoaiXeId = loaiXe.Id,
                            SoVe = txtSoVe.Text.Trim(),
                            BienSoXe = txtBiensovao.Text.ToUpper(),
                            NgayVao = DateTime.Now,
                            GiaTien = loaiXe.GiaTien,
                            //ImgBienXeVao = this.imageArray.NameBienSoUrl,
                            ImgVaoTruoc = this.imageArray.NameTruocUrl,
                            ImgVaoSau = this.imageArray.NameSauUrl,
                            Status = (!userType),
                            Created = DateTime.Now,
                            CreatedBy = Constants.CurrentUser,
                            Modified = DateTime.Now,
                            ModifiedBy = Constants.CurrentUser
                        };
                }

            }
            else
            {
                //wroteImage2 = false;
                AlertList.Error("Không ghi được ảnh chụp từ camera sau. Vui lòng thử lại...");
            }

            //Timer_Vao.Enabled = true;
            if (picSau.Image != null)
            {
                cds = proc.analyze((Bitmap)picSau.Image, 120);
                if (cds.Count > 0)
                {
                    foreach (Candidate cd in cds)
                    {
                        txtBiensovao.Text = cd.text;
                    }
                }
                else
                    txtBiensovao.Text = "";
            }

            autoCount = 0;

        }

        void axLiveTruoc_OnGetPicture(object sender, AxLIVEXLib._DLiveXEvents_OnGetPictureEvent e)
        {
            if (countT == 1)
            {
                return;
            }

            axLiveSau.StartGrapImage(true);
            countS = 0;
            this.imageArray = new ImgageArrayVao(tempFile, fileUtil.tempFolderToday);

            countT = 1;
            axLiveTruoc.StartGrapImage(false);
            imgT = ImageProcess.ImageConvert.GetImageFromIPicture(e.mPict);

            picTruoc.Image = imgT;

            if (!fileUtil.WriteImage(picTruoc.Image, imageArray.NameTruoc, "V"))
            {
                AlertList.Error("Không ghi được ảnh chụp từ camera trước. Vui lòng thử lại.");
            }
        }

        public void frmXeVao_Load(object sender, EventArgs e)
        {
            foreach (LoaiXe loaiXe in cbLoaixe.Items)
            {
                if (loaiXe.Ten.ToUpper().Equals(Constants.Xe.XeMay.ToUpper()))
                {
                    cbLoaixe.SelectedItem = loaiXe;
                    break;
                }
            }
            //Save();
            //asyCallBack = new AsyncCallback(TraningCompleted);
            //ManualReset = new ManualResetEvent(false);

            var item = _configCamera.ToList().ToList().FirstOrDefault(p => p.ComputerName.Contains(_computerName));
            if (item != null)
            {
                int pos = item.CardReader.IndexOf('|');
                if (pos < 0 || (item.CardReader[pos + 1] != '|' && item.CardReader[pos + 2] != '|'))
                    AlertList.Information("Không xác định được thiết bị đọc thẻ. Vui lòng thiết lập cài đặt.");
                else
                {
                    readerDevideVao = item.CardReader.Substring(0, pos);
                    readerDevideRa = item.CardReader.Substring(pos + 3);
                }

                this.axLiveTruoc.IpAddress = item.Server;
                this.axLiveTruoc.CommandPort = System.Convert.ToInt32("4550");
                this.axLiveTruoc.DataPort = System.Convert.ToInt32("5550");
                this.axLiveTruoc.AudioDataPort = System.Convert.ToInt32("6550");
                this.axLiveTruoc.DisablePWD = true;
                this.axLiveTruoc.DefaultCam = short.Parse(item.Cam1.ToString());
                this.axLiveTruoc.UserName = item.UserID;
                this.axLiveTruoc.Password = item.Password;
                this.axLiveTruoc.PlayX();

                this.axLiveSau.IpAddress = item.Server;
                this.axLiveSau.CommandPort = System.Convert.ToInt32("4550");
                this.axLiveSau.DataPort = System.Convert.ToInt32("5550");
                this.axLiveSau.AudioDataPort = System.Convert.ToInt32("6550");
                this.axLiveSau.DisablePWD = true;
                this.axLiveSau.DefaultCam = short.Parse(item.Cam2.ToString()); ;
                this.axLiveSau.UserName = item.UserID;
                this.axLiveSau.Password = item.Password;
                this.axLiveSau.PlayX();
            }
            else
            {
                AlertList.Warning("Bạn phải thiết lập camera và thiết bị đọc thẻ cho hệ thống trước khi sử dụng.");
            }

            this.Icon = new Icon(this.Icon, this.Icon.Size);
        }

        private void TiepTuc()
        {
            if (_model != null)
            {
                Insert();
                userType = false;
                _model = null;
            }

            txtSoVe.Focus();
        }

        private void timerClock_Tick(object sender, EventArgs e)
        {
            if (autoCount == 100)
            {
                if (_model != null)
                {
                    //btnTiep.PerformClick();
                    TiepTuc();
                }
                _veTemp = cardNumber;
                autoCount = 0;
                GC.Collect();
            }
            else
            {
                autoCount++;
            }
            //valid card
            //ValidCard();

        }

        private void txtBiensovao_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            txtBiensovao.ReadOnly = false;
            txtBiensovao.SelectAll();
        }

        private void cbLoaixe_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (((LoaiXe)cbLoaixe.SelectedItem).Ten.ToUpper().Equals(Constants.Xe.XeDap.ToUpper()))
            {
                rand = new Random();
                do
                {
                    _veXeDap = rand.Next(100, 999).ToString();
                } while (_veXeDap.Equals(txtBiensovao.Text));
                //if (!string.IsNullOrEmpty(txtSoVe.Text.Trim()))
                //{
                //    txtBiensovao.Text = txtSoVe.Text.Trim().Substring(6, 4);
                //}
                txtBiensovao.Text = _veXeDap;

            }

        }

        private void frmXeVao_KeyDown(object sender, KeyEventArgs e)
        {
            if (!isCardReaderVao && !isCardReaderRa)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    if (!txtSoVe.Focused && cardStatus.Equals(string.Empty))
                    {

                        //btnTiep.PerformClick();
                        TiepTuc();
                        cbLoaixe.SelectedItem = cbLoaixe.Items[1];

                    }
                    else if (!txtSoVe.Focused && !cardStatus.Equals(string.Empty))
                    {
                        AlertList.Error(cardStatus);
                    }
                }
                else if (e.KeyCode == Keys.F1)
                {
                    cardNumber = string.Empty;
                    txtSoVe.Text = string.Empty;
                    txtSoVe.Focus();
                }
                else if (e.KeyCode == Keys.F3)
                {
                    cbLoaixe.SelectedItem = cbLoaixe.Items[1];
                    cbLoaixe.SelectedItem = cbLoaixe.Items[0];
                    //txtSoVe.Text = string.Empty;
                    txtBiensovao.Focus();
                }
                else if (e.KeyCode == Keys.F4)
                {
                    cbLoaixe.SelectedItem = cbLoaixe.Items[1];
                    txtSoVe.Focus();
                }
                else if (e.KeyCode == Keys.F5)
                {
                    cbLoaixe.SelectedItem = cbLoaixe.Items[2];
                    txtSoVe.Focus();
                }
            }
        }

        private void txtSoVe_MouseEnter(object sender, EventArgs e)
        {
            txtSoVe.SelectAll();
        }

        private void txtSoVe_MouseDown(object sender, MouseEventArgs e)
        {
            txtSoVe.SelectAll();
        }

        private void frmXeVao_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (isCardReaderVao)
            {
                ReadFromCardReader(e);
                if (readOk)
                {
                    cardStatus = string.Empty;
                    //timerClock.Enabled = true;
                    txtSoVe.Text = cardNumber;
                    tempFile = DateTime.Now.ToString("yyyyMMddHHmmssffff") + "_" + _computerName;

                    axLiveTruoc.StartGrapImage(true);
                    countT = 0;

                    if (_model != null && _veTemp != cardNumber)
                    {
                        //btnTiep.PerformClick();
                        TiepTuc();
                    }
                    _veTemp = cardNumber;
                    txtBiensovao.Focus();
                    txtBiensovao.SelectAll();
                    autoCount = 0;
                }
            }
            //GC.Collect();

        }

        private void frmXeVao_FormClosed(object sender, FormClosedEventArgs e)
        {
            _rawinput.KeyPressed -= OnKeyPressed;
            GC.Collect();
        }

        private void txtBiensovao_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!isCardReaderVao && !isCardReaderRa)
            {
                if (char.IsLetterOrDigit(e.KeyChar))
                {
                    userType = true;
                }
            }
        }

        #endregion

        #region Private Method

        private void LoadLoaiXe()
        {
            var loaixe = _loaiXe.ToList().ToList();
            foreach (LoaiXe loai in loaixe)
            {
                cbLoaixe.Items.Add(loai);
            }
        }

        #region Validation

        private void ValidCard()
        {
            _veXe = Program.Container.Resolve<IService<VeXe>>();
            _xe = Program.Container.Resolve<IService<XeTemp>>();

            _veXe2 = _veXe.Detail(txtSoVe.Text.Trim());

            _xe2 = _xe.GetByMaxValue("SoVe", "NgayVao", "XeTemp", txtSoVe.Text.Trim());

            if (txtSoVe.Text.Trim().Equals(string.Empty))
            {
                lblTrangThaiThe.Text = @"Đang chờ";
                lblTrangThaiThe.ForeColor = Color.Black;
            }

            else if (_veXe2 == null)
            {
                lblTrangThaiThe.Text = Constants.VeMessages.VeKhongCoTrongDuLieu;
                cardStatus = Constants.VeMessages.VeKhongCoTrongDuLieu;
                lblTrangThaiThe.ForeColor = Color.Red;
                AlertList.Error(cardStatus);
            }

            else if (_veXe2.Status.Equals(Constants.StatusVeXe.MatVe))
            {
                lblTrangThaiThe.Text = Constants.VeMessages.MatVe;
                cardStatus = Constants.VeMessages.MatVe;
                lblTrangThaiThe.ForeColor = Color.Red;
                AlertList.Error(cardStatus);
            }

            else if (_veXe2.Status.Equals(Constants.StatusVeXe.InActive))
            {
                lblTrangThaiThe.Text = Constants.VeMessages.VeKhongHoatDong;
                cardStatus = Constants.VeMessages.VeKhongHoatDong;
                lblTrangThaiThe.ForeColor = Color.Red;
                AlertList.Error(cardStatus);
            }

            else if (_xe2 != null && _xe2.NgayRa == null && _xe2.ImgRaTruoc == null && _xe2.ImgRaSau == null)
            {
                lblTrangThaiThe.Text = Constants.VeMessages.VeChuaRa;
                cardStatus = Constants.VeMessages.VeChuaRa;
                lblTrangThaiThe.ForeColor = Color.Red;
                AlertList.Error(cardStatus);
            }

            else if (cbLoaixe.SelectedItem == null)
            {
                AlertList.Error("Bạn chưa chọn loại xe. Xin vui lòng kiểm tra lại");
                cbLoaixe.Focus();
            }
            else
            {
                lblTrangThaiThe.Text = Constants.VeMessages.VeHopLe;
                lblTrangThaiThe.ForeColor = Color.Blue;

            }
            _veXe2 = null;
            _xe2 = null;
        }

        #endregion

        #region Insert

        protected void Insert()
        {
            try
            {
                _model.BienSoXe = txtBiensovao.Text.ToUpper();
                _xe.Create(_model);

                //Reset controls
                //doInserted = true;
                //if (!isFromClick)
                //{
                //_model = null;
                //cardStatus = string.Empty;
                //txtSoVe.Text = string.Empty;
                //txtBiensovao.Text = string.Empty;
                //txtSoVe.Focus();
                //}

            }
            catch (Exception ex)
            {
                AlertList.Error("Lỗi phát sinh khi tạo thêm xe vào.");
                //AlertList.Error(ex.ToString());
            }
        }

        #endregion

        private static void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e)
        {
            var ex = e.ExceptionObject as Exception;

            if (null == ex) return;

            // Log this error. Logging the exception doesn't correct the problem but at least now
            // you may have more insight as to why the exception is being thrown.
            //Debug.WriteLine("Unhandled Exception: " + ex.Message);
            //Debug.WriteLine("Unhandled Exception: " + ex);
            MessageBox.Show(ex.Message);
        }

        private void OnKeyPressed(object sender, InputEventArg e)
        {
            if (e.KeyPressEvent.DeviceName.Equals(readerDevideVao))
            {
                isCardReaderVao = true;
                isCardReaderRa = false;
                txtBiensovao.ReadOnly = true;

            }
            else if (e.KeyPressEvent.DeviceName.Equals(readerDevideRa))
            {
                txtBiensovao.ReadOnly = true;
                isCardReaderVao = false;
                isCardReaderRa = true;
            }
            else
            {
                isCardReaderVao = false;
                isCardReaderRa = false;
                txtBiensovao.ReadOnly = false;
            }
        }

        private void ReadFromCardReader(KeyPressEventArgs e)
        {
            if (e.KeyChar != 13)
            {
                tempNumber = tempNumber + e.KeyChar;
                readOk = false;
                e.Handled = true;
            }
            else
            {
                cardNumber = tempNumber;
                tempNumber = string.Empty;
                readOk = true;

            }
        }

        #endregion

        #region Nhan dien bien so

        /// <summary>
        /// Get data from devices
        /// </summary>
        //private void CaptureWc()
        //{
        //    try
        //    {
        //        //Camera sau
        //        _cap0 = new Capture(_cmr0);
        //        _cap0.ImageGrabbed += wc0;
        //        _cap0.Start();
        //        //Camera trước
        //        _cap1 = new Capture(_cmr1);
        //        _cap1.ImageGrabbed += Wc1DetectFace;
        //        _cap1.Start();
        //    }
        //    catch (Exception)
        //    {
        //        //MessageBox.Show(ex.Message);
        //    }

        //}

        //private void Wc1DetectFace(object sender, EventArgs e)
        //{
        //    try
        //    {
        //        var faceDetector1 = new CascadeClassifier("haarcascade_frontalface_default.xml");
        //        _img1 = _cap1.RetrieveBgrFrame();
        //        _imgGray1 = _img1.Convert<Gray, byte>();
        //        foreach (var face in faceDetector1.DetectMultiScale(_imgGray1, 1.1, 10, new Size(20, 20), Size.Empty))
        //        {
        //            _img1.Draw(face, new Bgr(Color.White), 1);
        //        }
        //        //imgVaoTruoc.Image = _img1;
        //        //picTruoc.Image = _img1.Bitmap;
        //    }
        //    catch (Exception ex)
        //    {

        //    }
        //}

        //private void wc0(object sender, EventArgs e)
        //{
        //    try
        //    {
        //        _img0 = _cap0.RetrieveBgrFrame();
        //        ////imgVaoSau.Image = _img0;
        //        //picSau.Image = _img0.Bitmap;
        //    }
        //    catch (Exception)
        //    {

        //    }
        //}
        //Neural Network Object With Output Type String 

        //private NeuralNetwork<string> neuralNetwork = null;

        ////Data Members Required For Neural Network
        //private Dictionary<string, double[]> TrainingSet;
        //private int av_ImageHeight = 0;
        //private int av_ImageWidth = 0;
        //private int NumOfPatterns = 0;

        //private void Save()
        //{

        //    string[] Images = Directory.GetFiles(Application.StartupPath + @"\ImageTrainning", "*.bmp");
        //    NumOfPatterns = Images.Length;
        //    av_ImageHeight = 0;
        //    av_ImageWidth = 0;
        //    foreach (string s in Images)
        //    {
        //        var Temp = new Bitmap(s);
        //        av_ImageHeight += Temp.Height;
        //        av_ImageWidth += Temp.Width;
        //        Temp.Dispose();
        //    }
        //    av_ImageHeight /= NumOfPatterns;
        //    av_ImageWidth /= NumOfPatterns;

        //    int networkInput = av_ImageHeight * av_ImageWidth;
        //    GenerateTrainingSet();
        //    CreateNeuralNetwork();
        //}

        //private void CreateNeuralNetwork()
        //{
        //    if (TrainingSet == null)
        //        throw new Exception("Unable to Create Neural Network As There is No Data to Train..");

        //    neuralNetwork = new NeuralNetwork<string>
        //        (new BP3Layer<string>(av_ImageHeight * av_ImageWidth, 295, 98, NumOfPatterns), TrainingSet);

        //    neuralNetwork.MaximumError = 1.1;
        //    neuralNetwork.LoadNetwork(Application.StartupPath + @"\ImageTrainning\Model.net");
        //}

        //private void GenerateTrainingSet()
        //{
        //    // string[] Patterns = Directory.GetFiles(@"C:\Users\bienphongvnn\Desktop\hinhanhhuanluyen", "*.bmp");
        //    string[] Patterns = Directory.GetFiles(Application.StartupPath + @"\ImageTrainning", "*.bmp");
        //    TrainingSet = new Dictionary<string, double[]>(Patterns.Length);
        //    foreach (string s in Patterns)
        //    {
        //        var Temp = new Bitmap(s);
        //        TrainingSet.Add(Path.GetFileNameWithoutExtension(s),
        //            ImageProcessing.ToMatrix(Temp, av_ImageHeight, av_ImageWidth));
        //        Temp.Dispose();
        //    }


        //}
        #endregion

        private void button1_Click_1(object sender, EventArgs e)
        {
            //try
            //{
            //    var loaiXe = cbLoaixe.SelectedItem as LoaiXe;

            //    for (int i = 0; i < 10000; i++)
            //    {
            //        var model = new XeTemp
            //        {
            //            Id = Guid.NewGuid(),
            //            LoaiXeId = loaiXe.Id,
            //            SoVe = txtSoVe.Text.Trim(),
            //            BienSoXe = txtBiensovao.Text.ToUpper(),
            //            NgayVao = DateTime.Now,
            //            GiaTien = loaiXe.GiaTien,
            //            ImgBienXeVao = this.imageArray.NameBienSoUrl,
            //            ImgVaoTruoc = this.imageArray.NameTruocUrl,
            //            ImgVaoSau = this.imageArray.NameSauUrl,
            //            Status = (!userType),
            //            Created = DateTime.Now,
            //            CreatedBy = Constants.CurrentUser,
            //            Modified = DateTime.Now,
            //            ModifiedBy = Constants.CurrentUser
            //        };
            //        _xe.Create(model);
            //    }

            //Reset controls
            //doInserted = true;
            //if (!isFromClick)
            //{
            //    cardStatus = string.Empty;
            //    txtSoVe.Text = string.Empty;
            //    txtBiensovao.Text = string.Empty;
            //    txtSoVe.Focus();
            //    //}

            //}
            //catch (Exception ex)
            //{
            //    //AlertList.Error("Lỗi phát sinh khi tạo mới dữ liệu.");
            //    AlertList.Error(ex.ToString());
            //}
        }


    }
}